package com.freedom.monitor.myeye.client;

import com.freedom.monitor.myeye.client.reap.ReapMap;
import com.freedom.monitor.myeye.client.report.Report;
import com.freedom.monitor.myeye.client.report.ReportMap;
import com.freedom.monitor.myeye.client.utils.Logger;
import com.freedom.monitor.myeye.client.utils.PropertyUtils;

/**
 * @author: 刘志强
 * @QQ :837500869 上报
 * @param product
 *            产品编码---比如:金融产品编码finalcialProduct,宝宝钱包babyMoney等,必须跟你在后台管理界面上配置的一样
 * @param service
 *            服务编码---比如:http,web,cache,redis,sql,rpc等,跟你在后台管理界面上配置的一样
 * @param subKey
 *            信息收集码---http对应着url,sql对应着sql模板,redis对应访问命令,rpc对应方法
 *            这个子key一定是一个命令或者模板，带参数的语句一定要把参数去掉，否则key会“爆炸" 比如以sql为例，原来的sql是
 *            select * from user where id='123',如果这么写 key很快就炸了，你可以调用函数时传递 select
 *            * from user where id='xxx' 这样的固定的SQL语句, 你自己看得懂就行了
 * @param succeed
 *            1:成功 0:失败---从业务角度来说是成功/失败,这个由业务自己来决定,框架不关心也不可能知道
 * @param costTime
 *            花费时间 单位毫秒---本次请求的耗时,单位为毫秒,这个时间请业务自己采集,框架不关心如何采集耗时信息，框架不侵入业务
 */
public class MetricsHelperUtils {
	//
	private static final String BLANK = " ";
	private static final String EMPTY = "";
	private static final String DEFAULT_PRODUCT = "defaultProduct";
	private static final String DEFAULT_SERVICE = "defaultService";
	private static Logger logger = Logger.getLogger(MetricsHelperUtils.class);

	//
	//
	// begin to invoke
	public static void report(String subKey, int succeed, int costTime) {
		String defaultProduct = PropertyUtils.getInstance().getProperty(DEFAULT_PRODUCT);
		String defaultService = PropertyUtils.getInstance().getProperty(DEFAULT_SERVICE);
		report(defaultProduct, defaultService, subKey, succeed, costTime);
	}

	public static void report(String service, String subKey, int succeed, int costTime) {
		String defaultProduct = PropertyUtils.getInstance().getProperty(DEFAULT_PRODUCT);
		report(defaultProduct, service, subKey, succeed, costTime);
	}

	public static void report(String product, String service, String subKey, int succeed, int costTime) {
		// 1)whether the parameter is valid
		if (null == product || (product = product.trim()).length() <= 0//
				|| //
				null == service || (service = service.trim()).length() <= 0//
				|| //
				null == subKey || (subKey = subKey.trim()).length() <= 0//
				|| //
				(succeed != 0 && succeed != 1)//
				|| costTime < 0//
		) {
			StringBuilder strBuilder = new StringBuilder("error message ---> ");
			strBuilder.append(product)//
					.append(BLANK).append(service)//
					.append(BLANK).append(subKey)//
					.append(BLANK).append(EMPTY + succeed)//
					.append(BLANK).append(EMPTY + costTime);//
			logger.warn(strBuilder.toString());
			return;
		}
		// 2)build report
		// 这里或许可以优化
		Report report = new Report();
		report.setProduct(product).setService(service)//
				.setSubKey(subKey)//
				.setSucceed(succeed).setCostTime(costTime);
		// 3)是否需要开启(product:service)收割线程?
		ReapMap.handle(report.getProduct(), report.getService());
		// 4)now ,we will merge into the Global ConcurrentHashMap
		ReportMap.handle(report);
	}

}
